package switchviz.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.channels.FileChannel;

import javax.swing.filechooser.FileFilter;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class FileOperations 
{
	public static final String FILE_FORMAT = "8859_1";
	
	public static void saveXML(File filename, Document doc) throws IOException
	{
		if (filename == null) { return; }
		if (!filename.getName().endsWith(".xml"))
			filename = new File(filename.getParent(), filename.getName() + ".xml");
		XMLOutputter serializer = new XMLOutputter();
		Format format = Format.getPrettyFormat();
		format.setEncoding("ISO-8859-1");
	    
		BufferedWriter outfile = getISOWriter(filename);
		serializer.setFormat(format);
		serializer.output(doc, outfile);
		outfile.flush();
		outfile.close();
	}
	
	public static BufferedWriter getISOWriter(File file) throws UnsupportedEncodingException, FileNotFoundException
	{
		return new BufferedWriter( new OutputStreamWriter(new FileOutputStream(file), FILE_FORMAT));
	}
	
	public static BufferedReader getISOReader(File file) throws UnsupportedEncodingException, FileNotFoundException
	{
		return new BufferedReader( new InputStreamReader(new FileInputStream(file), FILE_FORMAT));
	}
	
	/**
	 * doesn't like xml files with dtd implementations....
	 * @param file
	 * @param rootname
	 * @return
	 * @throws JDOMException
	 * @throws IOException
	 */
	public static boolean testXMLRootName(File file, String rootname) throws JDOMException, IOException
	{
		if (file.exists()) 
		{ 
			SAXBuilder parser = new SAXBuilder();
			parser.setValidation(false);
			if (file.getName().contains("log4j")) { return false; }
			if(parser.build(file).getRootElement().getName().equals(rootname))
				return true;
		}
		return false;
	}
	
	public static void deleteFile(File file) throws IOException
	{
		if (!file.delete()) 
	    	throw new IOException();
	}
	
	public static boolean deleteAll(File dir)
	{
		if (dir.isDirectory()) 
		{
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) 
            {
                boolean success = deleteAll(new File(dir, children[i]));
                if (!success) 
                    return false;
            }
        }
        return dir.delete();
	}
	
	public static void copyFile(File in, File out) throws Exception 
	{
		 if(out.exists())
		 {
			 out = new File(out.getParent(), "copy_" + out.getName());
			 copyFile(in, out);
			 return;
		 }

		 FileChannel ic = new FileInputStream(in).getChannel();
		 FileChannel oc = new FileOutputStream(out).getChannel();
		 ic.transferTo(0, ic.size(), oc);
		 ic.close();
		 oc.close();
	}
	
	public static void copyDirectory(File in, File out) throws Exception
	{
		if(out.exists())
		{
			out = new File(out.getParent(), "copy_" + out.getName());
			copyDirectory(in, out);
			return;
		}
		out.mkdir();
		for(File file : in.listFiles())
		{
			if(!file.isHidden())
				copyFile(file, new File(out, file.getName()));
		}
	}
	
	public static File getUniqueXMLInDir(File dir, String filename)
	{
		while(true)
		{
			if((new File(dir, filename + ".xml")).exists())
				filename = filename + "_1";
			else
				break;
		}
		return new File(dir, filename + ".xml");
	}
	
	public static File getUniqueDir(File dir, String foldername)
	{
		while(true)
		{
			if((new File(dir, foldername)).exists())
				foldername = foldername + "_1";
			else
				break;
		}
		File folder = (new File(dir, foldername));
		folder.mkdirs();
		return folder;
	}
	
	public static FileFilter getXMLFileFilter(String description)
	{
		final String descr = description;
		return new FileFilter() 
		{
            public boolean accept(File f) 
            {
                return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
            }
            public String getDescription() 
            {
                return descr;
            }
        };
	}
}

